#ifndef OPTIMIZATION_COST_MODEL_H
#define OPTIMIZATION_COST_MODEL_H

#include <map>
#include <string>
#include <vector>
#include <memory>
#include "ASTNode.h"

// 优化收益类型
enum class OptimizationBenefit {
    NONE = 0,
    LOW = 1,
    MEDIUM = 2,
    HIGH = 3,
    CRITICAL = 4
};

// 优化代价类型
enum class OptimizationCost {
    NONE = 0,
    LOW = 1,
    MEDIUM = 2,
    HIGH = 3,
    VERY_HIGH = 4
};

// 优化类型
enum class OptimizationType {
    CONSTANT_FOLDING,
    COMMON_SUBEXPRESSION_ELIMINATION,
    DEAD_CODE_ELIMINATION,
    ALGEBRAIC_OPTIMIZATION,
    LOOP_OPTIMIZATION,
    REGISTER_ALLOCATION,
    INLINING,
    VECTORIZATION
};

// 优化决策
struct OptimizationDecision {
    OptimizationType type;
    OptimizationBenefit benefit;
    OptimizationCost cost;
    double netBenefit;  // benefit - cost
    bool shouldApply;
    std::string reason;

    OptimizationDecision(OptimizationType t, OptimizationBenefit b, OptimizationCost c, bool apply, const std::string& r)
        : type(t), benefit(b), cost(c), shouldApply(apply), reason(r) {
        netBenefit = static_cast<double>(b) - static_cast<double>(c);
    }
};

// 代码质量指标
struct CodeQualityMetrics {
    int instructionCount;
    int memoryAccessCount;
    int registerUsage;
    int controlFlowComplexity;
    double estimatedExecutionTime;
    int codeSize;

    CodeQualityMetrics() : instructionCount(0), memoryAccessCount(0),
                          registerUsage(0), controlFlowComplexity(0),
                          estimatedExecutionTime(0.0), codeSize(0) {}
};

// 优化上下文
struct OptimizationContext {
    ASTNode* node;
    std::map<std::string, int> variableUsage;
    std::map<std::string, int> expressionFrequency;
    CodeQualityMetrics currentMetrics;
    CodeQualityMetrics projectedMetrics;
    std::vector<OptimizationDecision> availableOptimizations;

    OptimizationContext(ASTNode* n) : node(n) {}
};

// 代价评估器
class CostEvaluator {
private:
    std::map<OptimizationType, double> optimizationWeights;
    std::map<std::string, int> expressionComplexity;

    // 私有辅助方法
    OptimizationDecision evaluateConstantFolding(ASTNode* node, const OptimizationContext& context);
    OptimizationDecision evaluateCommonSubexpressionElimination(ASTNode* node, const OptimizationContext& context);
    OptimizationDecision evaluateDeadCodeElimination(ASTNode* node, const OptimizationContext& context);
    OptimizationDecision evaluateAlgebraicOptimization(ASTNode* node, const OptimizationContext& context);
    void calculateMetricsRecursive(ASTNode* node, CodeQualityMetrics& metrics);
    std::string generateExpressionKey(ASTNode* node);
    std::string extractVariableName(ASTNode* node);
    bool hasSideEffects(ASTNode* node);
    bool isZeroConstant(ASTNode* node);
    bool isOneConstant(ASTNode* node);
    bool isTrueConstant(ASTNode* node);
    bool isInstructionNode(ASTNode* node);

public:
    CostEvaluator();

    // 评估单个优化的代价和收益
    OptimizationDecision evaluateOptimization(OptimizationType type, ASTNode* node, const OptimizationContext& context);

    // 评估代码质量
    CodeQualityMetrics evaluateCodeQuality(ASTNode* node);

    // 计算表达式复杂度
    int calculateExpressionComplexity(ASTNode* node);

    // 评估优化后的代码质量
    CodeQualityMetrics projectOptimizedQuality(ASTNode* node, OptimizationType optimization);

    // 计算净收益
    double calculateNetBenefit(const OptimizationDecision& decision);
};

// 优化协调器
class OptimizationCoordinator {
private:
    std::vector<OptimizationType> optimizationOrder;
    std::map<OptimizationType, bool> optimizationEnabled;
    CostEvaluator costEvaluator;
    int maxIterations;
    double convergenceThreshold;

    // 私有辅助方法
    void optimizeNodeRecursively(ASTNode* node);
    void optimizeFunction(ASTNode* funcNode);
    void optimizeBlock(ASTNode* blockNode);
    void optimizeExpressionStatement(ASTNode* exprStmt, std::vector<std::unique_ptr<ASTNode>>& optimizedStatements);

public:
    OptimizationCoordinator();

    // 设置优化策略
    void setOptimizationOrder(const std::vector<OptimizationType>& order);
    void enableOptimization(OptimizationType type, bool enabled);
    void setMaxIterations(int iterations);
    void setConvergenceThreshold(double threshold);

    // 协调优化过程
    void coordinateOptimizations(ASTNode* root);

    // 迭代优化直到收敛
    bool optimizeUntilConvergence(ASTNode* root);

    // 选择最优优化序列
    std::vector<OptimizationDecision> selectOptimalOptimizations(ASTNode* node, const OptimizationContext& context);

    // 应用优化决策
    void applyOptimizationDecisions(ASTNode* root, const std::vector<OptimizationDecision>& decisions);

    // 检查优化收敛性
    bool hasConverged(const CodeQualityMetrics& before, const CodeQualityMetrics& after);

    // 生成优化报告
    void generateOptimizationReport(const std::vector<OptimizationDecision>& decisions);
};

#endif // OPTIMIZATION_COST_MODEL_H
